﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Parser.CSharpCodeParser
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Web.Razor.Editor;
using System.Web.Razor.Generator;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer;
using System.Web.Razor.Tokenizer.Symbols;

namespace System.Web.Razor.Parser
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Represents a C sharp code parser.</summary>
  public class CSharpCodeParser : 
    TokenizerBackedParser<CSharpTokenizer, CSharpSymbol, CSharpSymbolType>
  {
    internal static readonly int UsingKeywordLength = 5;
    internal static ISet<string> DefaultKeywords = (ISet<string>) new HashSet<string>()
    {
      "if",
      "do",
      "try",
      "for",
      "foreach",
      "while",
      "switch",
      "lock",
      "using",
      "section",
      "inherits",
      "helper",
      "functions",
      "namespace",
      "class",
      "layout",
      "sessionstate"
    };
    private Dictionary<string, Action> _directiveParsers = new Dictionary<string, Action>();
    private Dictionary<CSharpKeyword, Action<bool>> _keywordParsers = new Dictionary<CSharpKeyword, Action<bool>>();

    private void SetupDirectives()
    {
      this.MapDirectives(new Action(this.InheritsDirective), SyntaxConstants.CSharp.InheritsKeyword);
      this.MapDirectives(new Action(this.FunctionsDirective), SyntaxConstants.CSharp.FunctionsKeyword);
      this.MapDirectives(new Action(this.SectionDirective), SyntaxConstants.CSharp.SectionKeyword);
      this.MapDirectives(new Action(this.HelperDirective), SyntaxConstants.CSharp.HelperKeyword);
      this.MapDirectives(new Action(this.LayoutDirective), SyntaxConstants.CSharp.LayoutKeyword);
      this.MapDirectives(new Action(this.SessionStateDirective), SyntaxConstants.CSharp.SessionStateKeyword);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the layout directive.</summary>
    protected virtual void LayoutDirective()
    {
      this.AcceptAndMoveNext();
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Directive);
      bool flag1 = this.At(CSharpSymbolType.WhiteSpace);
      this.AcceptWhile(CSharpSymbolType.WhiteSpace);
      this.Output(SpanKind.MetaCode, flag1 ? AcceptedCharacters.None : AcceptedCharacters.Any);
      this.AcceptUntil(CSharpSymbolType.NewLine);
      this.Span.CodeGenerator = (ISpanCodeGenerator) new SetLayoutCodeGenerator((string) this.Span.GetContent());
      this.Span.EditHandler.EditorHints = EditorHints.VirtualPath | EditorHints.LayoutPage;
      bool flag2 = this.Optional(CSharpSymbolType.NewLine);
      this.AddMarkerSymbolIfNecessary();
      this.Output(SpanKind.MetaCode, flag2 ? AcceptedCharacters.None : AcceptedCharacters.Any);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates a session state directive.</summary>
    protected virtual void SessionStateDirective()
    {
      this.AcceptAndMoveNext();
      this.SessionStateDirectiveCore();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the session state directive core.</summary>
    protected void SessionStateDirectiveCore() => this.SessionStateTypeDirective(RazorResources.ParserEror_SessionDirectiveMissingValue, (Func<string, string, SpanCodeGenerator>) ((key, value) => (SpanCodeGenerator) new RazorDirectiveAttributeCodeGenerator(key, value)));

    /// <summary>Indicates the directive for session state type.</summary>
    /// <param name="noValueError">The no value error.</param>
    /// <param name="createCodeGenerator">The create code generator.</param>
    protected void SessionStateTypeDirective(
      string noValueError,
      Func<string, string, SpanCodeGenerator> createCodeGenerator)
    {
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Directive);
      CSharpSymbol symbol = this.AcceptSingleWhiteSpaceCharacter();
      if (this.Span.Symbols.Count > 1)
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Output(SpanKind.MetaCode);
      if (symbol != null)
        this.Accept(symbol);
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, true));
      if (!this.ValidSessionStateValue())
        this.Context.OnError(this.CurrentLocation, noValueError);
      string str = string.Concat(this.Span.Symbols.Cast<CSharpSymbol>().Select<CSharpSymbol, string>((Func<CSharpSymbol, string>) (sym => sym.Content))).Trim();
      this.Span.CodeGenerator = (ISpanCodeGenerator) createCodeGenerator(SyntaxConstants.CSharp.SessionStateKeyword, str);
      this.CompleteBlock();
      this.Output(SpanKind.Code);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the value of the session state is valid.</summary>
    /// <returns>true if the value of the session state is valid; otherwise, false.</returns>
    protected virtual bool ValidSessionStateValue() => this.Optional(CSharpSymbolType.Identifier);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates a helper directive.</summary>
    protected virtual void HelperDirective()
    {
      int num = this.Context.IsWithin(BlockType.Helper) ? 1 : 0;
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Helper);
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(this.CurrentSymbol.Content.ToString().ToLowerInvariant(), this.CurrentLocation);
      this.AcceptAndMoveNext();
      if (num != 0)
        this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Helpers_Cannot_Be_Nested);
      if (!this.At(CSharpSymbolType.WhiteSpace))
      {
        string str;
        if (this.At(CSharpSymbolType.NewLine))
          str = RazorResources.ErrorComponent_Newline;
        else if (this.EndOfFile)
          str = RazorResources.ErrorComponent_EndOfFile;
        else
          str = string.Format((IFormatProvider) CultureInfo.CurrentCulture, RazorResources.ErrorComponent_Character, (object) this.CurrentSymbol.Content);
        this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start, (object) str);
        this.PutCurrentBack();
        this.Output(SpanKind.MetaCode);
      }
      else
      {
        CSharpSymbol symbol = this.AcceptSingleWhiteSpaceCharacter();
        this.Output(SpanKind.MetaCode);
        if (symbol != null)
          this.Accept(symbol);
        this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, true));
        bool flag = !this.Required(CSharpSymbolType.Identifier, true, RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start);
        if (!flag)
          this.AcceptAndMoveNext();
        this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, true));
        SourceLocation currentLocation1 = this.CurrentLocation;
        if (!this.Optional(CSharpSymbolType.LeftParenthesis))
        {
          if (!flag)
          {
            flag = true;
            this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_MissingCharAfterHelperName, (object) "(");
          }
        }
        else
        {
          if (!this.Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftParenthesis, CSharpSymbolType.RightParenthesis, this.CurrentLocation))
          {
            flag = true;
            this.Context.OnError(currentLocation1, RazorResources.ParseError_UnterminatedHelperParameterList);
          }
          this.Optional(CSharpSymbolType.RightParenthesis);
        }
        int absoluteIndex = this.CurrentLocation.AbsoluteIndex;
        IEnumerable<CSharpSymbol> symbols = this.ReadWhile(CSharpCodeParser.IsSpacingToken(true, true));
        SourceLocation currentLocation2 = this.CurrentLocation;
        bool headerComplete = this.At(CSharpSymbolType.LeftBrace);
        if (headerComplete)
        {
          this.Accept(symbols);
          this.AcceptAndMoveNext();
        }
        else
        {
          this.Context.Source.Position = absoluteIndex;
          this.NextToken();
          this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, true));
          if (!flag)
            this.Context.OnError(currentLocation2, RazorResources.ParseError_MissingCharAfterHelperParameters, (object) this.Language.GetSample(CSharpSymbolType.LeftBrace));
        }
        this.AddMarkerSymbolIfNecessary();
        HelperCodeGenerator helperCodeGenerator = new HelperCodeGenerator(this.Span.GetContent(), headerComplete);
        this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) helperCodeGenerator;
        this.Span.CodeGenerator = SpanCodeGenerator.Null;
        if (!headerComplete)
        {
          this.CompleteBlock();
          this.Output(SpanKind.Code);
        }
        else
        {
          this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
          this.Output(SpanKind.Code);
          AutoCompleteEditHandler completeEditHandler = new AutoCompleteEditHandler(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString));
          using (this.PushSpanConfig(new Action<SpanBuilder>(this.DefaultSpanConfig)))
          {
            using (this.Context.StartBlock(BlockType.Statement))
            {
              this.Span.EditHandler = (SpanEditHandler) completeEditHandler;
              this.CodeBlock(false, block);
              this.CompleteBlock(true);
              this.Output(SpanKind.Code);
            }
          }
          this.Initialize(this.Span);
          this.EnsureCurrent();
          this.Span.CodeGenerator = SpanCodeGenerator.Null;
          if (!this.Optional(CSharpSymbolType.RightBrace))
          {
            completeEditHandler.AutoCompleteString = "}";
            completeEditHandler.AcceptedCharacters = AcceptedCharacters.Any;
          }
          else
          {
            helperCodeGenerator.Footer = this.Span.GetContent();
            this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
          }
          this.CompleteBlock();
          this.Output(SpanKind.Code);
        }
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates a section directive.</summary>
    protected virtual void SectionDirective()
    {
      int num = this.Context.IsWithin(BlockType.Section) ? 1 : 0;
      bool flag = false;
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Section);
      this.AcceptAndMoveNext();
      if (num != 0)
      {
        this.Context.OnError(this.CurrentLocation, string.Format((IFormatProvider) CultureInfo.CurrentCulture, RazorResources.ParseError_Sections_Cannot_Be_Nested, (object) RazorResources.SectionExample_CS));
        flag = true;
      }
      IEnumerable<CSharpSymbol> symbols1 = this.ReadWhile(CSharpCodeParser.IsSpacingToken(true, false));
      string sectionName = string.Empty;
      if (!this.Required(CSharpSymbolType.Identifier, true, RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start))
      {
        if (!flag)
          flag = true;
        this.PutCurrentBack();
        this.PutBack(symbols1);
        this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, false));
      }
      else
      {
        this.Accept(symbols1);
        sectionName = this.CurrentSymbol.Content;
        this.AcceptAndMoveNext();
      }
      this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new SectionCodeGenerator(sectionName);
      SourceLocation currentLocation = this.CurrentLocation;
      IEnumerable<CSharpSymbol> symbols2 = this.ReadWhile(CSharpCodeParser.IsSpacingToken(true, false));
      if (!this.At(CSharpSymbolType.LeftBrace))
      {
        if (!flag)
          this.Context.OnError(currentLocation, RazorResources.ParseError_MissingOpenBraceAfterSection);
        this.PutCurrentBack();
        this.PutBack(symbols2);
        this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, false));
        this.Optional(CSharpSymbolType.NewLine);
        this.Output(SpanKind.MetaCode);
        this.CompleteBlock();
      }
      else
      {
        this.Accept(symbols2);
        AutoCompleteEditHandler completeEditHandler = new AutoCompleteEditHandler(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString))
        {
          AutoCompleteAtEndOfSpan = true
        };
        this.Span.EditHandler = (SpanEditHandler) completeEditHandler;
        this.Span.Accept((ISymbol) this.CurrentSymbol);
        this.Output(SpanKind.MetaCode);
        this.SectionBlock("{", "}", true);
        this.Span.CodeGenerator = SpanCodeGenerator.Null;
        if (!this.Optional(CSharpSymbolType.RightBrace))
        {
          completeEditHandler.AutoCompleteString = "}";
          this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Expected_X, (object) this.Language.GetSample(CSharpSymbolType.RightBrace));
        }
        else
          this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
        this.CompleteBlock(false, true);
        this.Output(SpanKind.MetaCode);
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the functions directive.</summary>
    protected virtual void FunctionsDirective()
    {
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Functions);
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(this.CurrentSymbol);
      this.AcceptAndMoveNext();
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, false));
      if (!this.At(CSharpSymbolType.LeftBrace))
      {
        this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Expected_X, (object) this.Language.GetSample(CSharpSymbolType.LeftBrace));
        this.CompleteBlock();
        this.Output(SpanKind.MetaCode);
      }
      else
      {
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
        SourceLocation currentLocation = this.CurrentLocation;
        this.AcceptAndMoveNext();
        this.Output(SpanKind.MetaCode);
        AutoCompleteEditHandler completeEditHandler = new AutoCompleteEditHandler(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString));
        this.Span.EditHandler = (SpanEditHandler) completeEditHandler;
        this.Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftBrace, CSharpSymbolType.RightBrace, currentLocation);
        this.Span.CodeGenerator = (ISpanCodeGenerator) new TypeMemberCodeGenerator();
        if (!this.At(CSharpSymbolType.RightBrace))
        {
          completeEditHandler.AutoCompleteString = "}";
          this.Context.OnError(block.Start, RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, (object) block.Name, (object) "}", (object) "{");
          this.CompleteBlock();
          this.Output(SpanKind.Code);
        }
        else
        {
          this.Output(SpanKind.Code);
          this.Span.CodeGenerator = SpanCodeGenerator.Null;
          this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
          this.AcceptAndMoveNext();
          this.CompleteBlock();
          this.Output(SpanKind.MetaCode);
        }
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates which class the application will derive the view from, and can therefore ensure proper type checking.</summary>
    protected virtual void InheritsDirective()
    {
      this.AcceptAndMoveNext();
      this.InheritsDirectiveCore();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Asserts a directive code.</summary>
    /// <param name="directive">The directive code to assert.</param>
    [Conditional("DEBUG")]
    protected void AssertDirective(string directive)
    {
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Inherits a directive core.</summary>
    protected void InheritsDirectiveCore() => this.BaseTypeDirective(RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, (Func<string, SpanCodeGenerator>) (baseType => (SpanCodeGenerator) new SetBaseTypeCodeGenerator(baseType)));

    /// <summary>Indicates the base type directive.</summary>
    /// <param name="noTypeNameError">The no type name error.</param>
    /// <param name="createCodeGenerator">The create code generator.</param>
    protected void BaseTypeDirective(
      string noTypeNameError,
      Func<string, SpanCodeGenerator> createCodeGenerator)
    {
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Directive);
      CSharpSymbol symbol = this.AcceptSingleWhiteSpaceCharacter();
      if (this.Span.Symbols.Count > 1)
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Output(SpanKind.MetaCode);
      if (symbol != null)
        this.Accept(symbol);
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, true));
      if (this.EndOfFile || this.At(CSharpSymbolType.WhiteSpace) || this.At(CSharpSymbolType.NewLine))
        this.Context.OnError(this.CurrentLocation, noTypeNameError);
      this.AcceptUntil(CSharpSymbolType.NewLine);
      if (!this.Context.DesignTimeMode)
        this.Optional(CSharpSymbolType.NewLine);
      string content = (string) this.Span.GetContent();
      this.Span.CodeGenerator = (ISpanCodeGenerator) createCodeGenerator(content.Trim());
      this.CompleteBlock();
      this.Output(SpanKind.Code);
    }

    private void SetUpKeywords()
    {
      this.MapKeywords(new Action<bool>(this.ConditionalBlock), CSharpKeyword.For, CSharpKeyword.Foreach, CSharpKeyword.While, CSharpKeyword.Switch, CSharpKeyword.Lock);
      this.MapKeywords(new Action<bool>(this.CaseStatement), false, CSharpKeyword.Case, CSharpKeyword.Default);
      this.MapKeywords(new Action<bool>(this.IfStatement), CSharpKeyword.If);
      this.MapKeywords(new Action<bool>(this.TryStatement), CSharpKeyword.Try);
      this.MapKeywords(new Action<bool>(this.UsingKeyword), CSharpKeyword.Using);
      this.MapKeywords(new Action<bool>(this.DoStatement), CSharpKeyword.Do);
      this.MapKeywords(new Action<bool>(this.ReservedDirective), CSharpKeyword.Namespace, CSharpKeyword.Class);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the reserved directive.</summary>
    /// <param name="topLevel">Determines whether the directive is a top level.</param>
    protected virtual void ReservedDirective(bool topLevel)
    {
      this.Context.OnError(this.CurrentLocation, string.Format((IFormatProvider) CultureInfo.CurrentCulture, RazorResources.ParseError_ReservedWord, (object) this.CurrentSymbol.Content));
      this.AcceptAndMoveNext();
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Span.CodeGenerator = SpanCodeGenerator.Null;
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Directive);
      this.CompleteBlock();
      this.Output(SpanKind.MetaCode);
    }

    private void KeywordBlock(bool topLevel) => this.HandleKeyword(topLevel, (Action) (() =>
    {
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Expression);
      this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new ExpressionCodeGenerator();
      this.ImplicitExpression();
    }));

    private void CaseStatement(bool topLevel)
    {
      this.AcceptUntil(CSharpSymbolType.Colon);
      this.Optional(CSharpSymbolType.Colon);
    }

    private void DoStatement(bool topLevel)
    {
      this.UnconditionalBlock();
      this.WhileClause();
      if (!topLevel)
        return;
      this.CompleteBlock();
    }

    private void WhileClause()
    {
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
      IEnumerable<CSharpSymbol> nextImportantToken = this.SkipToNextImportantToken();
      if (this.At(CSharpKeyword.While))
      {
        this.Accept(nextImportantToken);
        this.AcceptAndMoveNext();
        this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
        if (!this.AcceptCondition() || !this.Optional(CSharpSymbolType.Semicolon))
          return;
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      }
      else
      {
        this.PutCurrentBack();
        this.PutBack(nextImportantToken);
      }
    }

    private void UsingKeyword(bool topLevel)
    {
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(this.CurrentSymbol);
      this.AcceptAndMoveNext();
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(false, true));
      if (this.At(CSharpSymbolType.LeftParenthesis))
        this.UsingStatement(block);
      else if (this.At(CSharpSymbolType.Identifier))
      {
        if (!topLevel)
        {
          this.Context.OnError(block.Start, RazorResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock);
          this.StandardStatement();
        }
        else
          this.UsingDeclaration();
      }
      if (!topLevel)
        return;
      this.CompleteBlock();
    }

    private void UsingDeclaration()
    {
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Directive);
      this.NamespaceOrTypeName();
      IEnumerable<CSharpSymbol> symbols = this.ReadWhile(CSharpCodeParser.IsSpacingToken(true, true));
      if (this.At(CSharpSymbolType.Assign))
      {
        this.Accept(symbols);
        this.AcceptAndMoveNext();
        this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
        this.NamespaceOrTypeName();
      }
      else
      {
        this.PutCurrentBack();
        this.PutBack(symbols);
      }
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.AnyExceptNewline;
      this.Span.CodeGenerator = (ISpanCodeGenerator) new AddImportCodeGenerator((string) this.Span.GetContent((Func<IEnumerable<ISymbol>, IEnumerable<ISymbol>>) (syms => syms.Skip<ISymbol>(1))), SyntaxConstants.CSharp.UsingKeywordLength);
      if (!this.EnsureCurrent())
        return;
      this.Optional(CSharpSymbolType.Semicolon);
    }

    private bool NamespaceOrTypeName()
    {
      if (!this.Optional(CSharpSymbolType.Identifier) && !this.Optional(CSharpSymbolType.Keyword))
        return false;
      this.Optional(CSharpSymbolType.QuestionMark);
      if (this.Optional(CSharpSymbolType.DoubleColon) && !this.Optional(CSharpSymbolType.Identifier))
        this.Optional(CSharpSymbolType.Keyword);
      if (this.At(CSharpSymbolType.LessThan))
        this.TypeArgumentList();
      if (this.Optional(CSharpSymbolType.Dot))
        this.NamespaceOrTypeName();
      while (this.At(CSharpSymbolType.LeftBracket))
      {
        this.Balance(BalancingModes.None);
        this.Optional(CSharpSymbolType.RightBracket);
      }
      return true;
    }

    private void TypeArgumentList()
    {
      this.Balance(BalancingModes.None);
      this.Optional(CSharpSymbolType.GreaterThan);
    }

    private void UsingStatement(CSharpCodeParser.Block block)
    {
      if (!this.AcceptCondition())
        return;
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
      this.ExpectCodeBlock(block);
    }

    private void TryStatement(bool topLevel)
    {
      this.UnconditionalBlock();
      this.AfterTryClause();
      if (!topLevel)
        return;
      this.CompleteBlock();
    }

    private void IfStatement(bool topLevel)
    {
      this.ConditionalBlock(false);
      this.AfterIfClause();
      if (!topLevel)
        return;
      this.CompleteBlock();
    }

    private void AfterTryClause()
    {
      IEnumerable<CSharpSymbol> nextImportantToken = this.SkipToNextImportantToken();
      if (this.At(CSharpKeyword.Catch))
      {
        this.Accept(nextImportantToken);
        this.ConditionalBlock(false);
        this.AfterTryClause();
      }
      else if (this.At(CSharpKeyword.Finally))
      {
        this.Accept(nextImportantToken);
        this.UnconditionalBlock();
      }
      else
      {
        this.PutCurrentBack();
        this.PutBack(nextImportantToken);
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
      }
    }

    private void AfterIfClause()
    {
      IEnumerable<CSharpSymbol> nextImportantToken = this.SkipToNextImportantToken();
      if (this.At(CSharpKeyword.Else))
      {
        this.Accept(nextImportantToken);
        this.ElseClause();
      }
      else
      {
        this.PutCurrentBack();
        this.PutBack(nextImportantToken);
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
      }
    }

    private void ElseClause()
    {
      if (!this.At(CSharpKeyword.Else))
        return;
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(this.CurrentSymbol);
      this.AcceptAndMoveNext();
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
      if (this.At(CSharpKeyword.If))
      {
        block.Name = SyntaxConstants.CSharp.ElseIfKeyword;
        this.ConditionalBlock(block);
        this.AfterIfClause();
      }
      else
      {
        if (this.EndOfFile)
          return;
        this.ExpectCodeBlock(block);
      }
    }

    private void ExpectCodeBlock(CSharpCodeParser.Block block)
    {
      if (this.EndOfFile)
        return;
      if (!this.At(CSharpSymbolType.LeftBrace))
        this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_SingleLine_ControlFlowStatements_Not_Allowed, (object) this.Language.GetSample(CSharpSymbolType.LeftBrace), (object) this.CurrentSymbol.Content);
      this.Statement(block);
    }

    private void UnconditionalBlock()
    {
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(this.CurrentSymbol);
      this.AcceptAndMoveNext();
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
      this.ExpectCodeBlock(block);
    }

    private void ConditionalBlock(bool topLevel)
    {
      this.ConditionalBlock(new CSharpCodeParser.Block(this.CurrentSymbol));
      if (!topLevel)
        return;
      this.CompleteBlock();
    }

    private void ConditionalBlock(CSharpCodeParser.Block block)
    {
      this.AcceptAndMoveNext();
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
      if (!this.AcceptCondition())
        return;
      this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
      this.ExpectCodeBlock(block);
    }

    private bool AcceptCondition()
    {
      if (!this.At(CSharpSymbolType.LeftParenthesis))
        return true;
      int num = this.Balance(BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates) ? 1 : 0;
      if (num == 0)
      {
        this.AcceptUntil(CSharpSymbolType.NewLine);
        return num != 0;
      }
      this.Optional(CSharpSymbolType.RightParenthesis);
      return num != 0;
    }

    private void Statement() => this.Statement((CSharpCodeParser.Block) null);

    private void Statement(CSharpCodeParser.Block block)
    {
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
      CSharpSymbol symbol = this.AcceptWhiteSpaceInLines();
      if (this.EndOfFile)
      {
        if (symbol == null)
          return;
        this.Accept(symbol);
      }
      else
      {
        CSharpSymbolType type = this.CurrentSymbol.Type;
        SourceLocation currentLocation = this.CurrentLocation;
        bool flag1 = type == CSharpSymbolType.Transition && this.NextIs(CSharpSymbolType.Colon);
        int num;
        if (!flag1)
        {
          switch (type)
          {
            case CSharpSymbolType.LessThan:
              break;
            case CSharpSymbolType.Transition:
              num = this.NextIs(CSharpSymbolType.LessThan) ? 1 : 0;
              goto label_8;
            default:
              num = 0;
              goto label_8;
          }
        }
        num = 1;
label_8:
        bool flag2 = num != 0;
        if (this.Context.DesignTimeMode || !flag2)
        {
          if (symbol != null)
            this.Accept(symbol);
        }
        else
        {
          this.PutCurrentBack();
          this.PutBack(symbol);
        }
        if (flag2)
        {
          if (type == CSharpSymbolType.Transition && !flag1)
            this.Context.OnError(currentLocation, RazorResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start);
          this.Output(SpanKind.Code);
          if (this.Context.DesignTimeMode && this.CurrentSymbol != null && (this.CurrentSymbol.Type == CSharpSymbolType.LessThan || this.CurrentSymbol.Type == CSharpSymbolType.Transition))
            this.PutCurrentBack();
          this.OtherParserBlock();
        }
        else
          this.HandleStatement(block, type);
      }
    }

    private void HandleStatement(CSharpCodeParser.Block block, CSharpSymbolType type)
    {
      switch (type)
      {
        case CSharpSymbolType.Keyword:
          this.HandleKeyword(false, new Action(this.StandardStatement));
          break;
        case CSharpSymbolType.Comment:
          this.AcceptAndMoveNext();
          break;
        case CSharpSymbolType.LeftBrace:
          block = block ?? new CSharpCodeParser.Block(RazorResources.BlockName_Code, this.CurrentLocation);
          this.AcceptAndMoveNext();
          this.CodeBlock(block);
          break;
        case CSharpSymbolType.RightBrace:
          break;
        case CSharpSymbolType.Transition:
          this.EmbeddedExpression();
          break;
        case CSharpSymbolType.RazorCommentTransition:
          this.Output(SpanKind.Code);
          this.RazorComment();
          this.Statement(block);
          break;
        default:
          this.StandardStatement();
          break;
      }
    }

    private void EmbeddedExpression()
    {
      CSharpSymbol currentSymbol = this.CurrentSymbol;
      this.NextToken();
      if (this.At(CSharpSymbolType.Transition))
      {
        this.Output(SpanKind.Code);
        this.Accept(currentSymbol);
        this.Span.CodeGenerator = SpanCodeGenerator.Null;
        this.Output(SpanKind.Code);
        this.AcceptAndMoveNext();
        this.StandardStatement();
      }
      else
      {
        if (this.At(CSharpSymbolType.Keyword))
          this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Unexpected_Keyword_After_At, (object) CSharpLanguageCharacteristics.GetKeyword(this.CurrentSymbol.Keyword.Value));
        else if (this.At(CSharpSymbolType.LeftBrace))
          this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Unexpected_Nested_CodeBlock);
        this.PutCurrentBack();
        this.PutBack(currentSymbol);
        this.AddMarkerSymbolIfNecessary();
        this.NestedBlock();
      }
    }

    private void StandardStatement()
    {
      while (!this.EndOfFile)
      {
        int absoluteIndex = this.CurrentLocation.AbsoluteIndex;
        IEnumerable<CSharpSymbol> symbols = this.ReadWhile((Func<CSharpSymbol, bool>) (sym => sym.Type != CSharpSymbolType.Semicolon && sym.Type != CSharpSymbolType.RazorCommentTransition && (sym.Type != CSharpSymbolType.Transition && sym.Type != CSharpSymbolType.LeftBrace) && (sym.Type != CSharpSymbolType.LeftParenthesis && sym.Type != CSharpSymbolType.LeftBracket) && sym.Type != CSharpSymbolType.RightBrace));
        if (this.At(CSharpSymbolType.LeftBrace) || this.At(CSharpSymbolType.LeftParenthesis) || this.At(CSharpSymbolType.LeftBracket))
        {
          this.Accept(symbols);
          if (this.Balance(BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates))
          {
            this.Optional(CSharpSymbolType.RightBrace);
          }
          else
          {
            this.AcceptUntil(CSharpSymbolType.LessThan, CSharpSymbolType.RightBrace);
            break;
          }
        }
        else
        {
          if (this.At(CSharpSymbolType.Transition))
          {
            if (this.NextIs(CSharpSymbolType.LessThan, CSharpSymbolType.Colon))
            {
              this.Accept(symbols);
              this.Output(SpanKind.Code);
              this.Template();
              continue;
            }
          }
          if (this.At(CSharpSymbolType.RazorCommentTransition))
          {
            this.Accept(symbols);
            this.RazorComment();
          }
          else
          {
            if (this.At(CSharpSymbolType.Semicolon))
            {
              this.Accept(symbols);
              this.AcceptAndMoveNext();
              break;
            }
            if (this.At(CSharpSymbolType.RightBrace))
            {
              this.Accept(symbols);
              break;
            }
            this.Context.Source.Position = absoluteIndex;
            this.NextToken();
            this.AcceptUntil(CSharpSymbolType.LessThan, CSharpSymbolType.RightBrace);
            break;
          }
        }
      }
    }

    private void CodeBlock(CSharpCodeParser.Block block) => this.CodeBlock(true, block);

    private void CodeBlock(bool acceptTerminatingBrace, CSharpCodeParser.Block block)
    {
      this.EnsureCurrent();
      while (!this.EndOfFile && !this.At(CSharpSymbolType.RightBrace))
      {
        this.Statement();
        this.EnsureCurrent();
      }
      if (this.EndOfFile)
      {
        this.Context.OnError(block.Start, RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, (object) block.Name, (object) '}', (object) '{');
      }
      else
      {
        if (!acceptTerminatingBrace)
          return;
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
        this.AcceptAndMoveNext();
      }
    }

    private void HandleKeyword(bool topLevel, Action fallback)
    {
      Action<bool> action;
      if (this._keywordParsers.TryGetValue(this.CurrentSymbol.Keyword.Value, out action))
        action(topLevel);
      else
        fallback();
    }

    private IEnumerable<CSharpSymbol> SkipToNextImportantToken()
    {
      while (!this.EndOfFile)
      {
        IEnumerable<CSharpSymbol> symbols = this.ReadWhile(CSharpCodeParser.IsSpacingToken(true, true));
        if (!this.At(CSharpSymbolType.RazorCommentTransition))
          return symbols;
        this.Accept(symbols);
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
        this.RazorComment();
      }
      return Enumerable.Empty<CSharpSymbol>();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Spans the output of the parsing before the comment.</summary>
    protected override void OutputSpanBeforeRazorComment()
    {
      this.AddMarkerSymbolIfNecessary();
      this.Output(SpanKind.Code);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Parser.CSharpCodeParser" /> class.</summary>
    public CSharpCodeParser()
    {
      this.Keywords = (ISet<string>) new HashSet<string>();
      this.SetUpKeywords();
      this.SetupDirectives();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the C sharp language keywords.</summary>
    /// <returns>The C sharp language keywords.</returns>
    protected internal ISet<string> Keywords { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets a value that indicates whether the code is nested.</summary>
    /// <returns>true if the code is nested; otherwise, false.</returns>
    public bool IsNested { get; set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the other parser used for the code.</summary>
    /// <returns>The other parser used for the code.</returns>
    protected override ParserBase OtherParser => this.Context.MarkupParser;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the specific language for parsing.</summary>
    /// <returns>The specific language for parsing.</returns>
    protected override LanguageCharacteristics<CSharpTokenizer, CSharpSymbol, CSharpSymbolType> Language => (LanguageCharacteristics<CSharpTokenizer, CSharpSymbol, CSharpSymbolType>) CSharpLanguageCharacteristics.Instance;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Maps the given directives.</summary>
    /// <param name="handler">The handler.</param>
    /// <param name="directives">The directives.</param>
    protected void MapDirectives(Action handler, params string[] directives)
    {
      foreach (string directive in directives)
      {
        this._directiveParsers.Add(directive, handler);
        this.Keywords.Add(directive);
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets a directive handler.</summary>
    /// <returns>true if successful; otherwise, false.</returns>
    /// <param name="directive">The directive.</param>
    /// <param name="handler">The handler.</param>
    protected bool TryGetDirectiveHandler(string directive, out Action handler) => this._directiveParsers.TryGetValue(directive, out handler);

    private void MapKeywords(Action<bool> handler, params CSharpKeyword[] keywords) => this.MapKeywords(handler, true, keywords);

    private void MapKeywords(Action<bool> handler, bool topLevel, params CSharpKeyword[] keywords)
    {
      foreach (CSharpKeyword keyword in keywords)
      {
        this._keywordParsers.Add(keyword, handler);
        if (topLevel)
          this.Keywords.Add(CSharpLanguageCharacteristics.GetKeyword(keyword));
      }
    }

    [Conditional("DEBUG")]
    internal void Assert(CSharpKeyword expectedKeyword)
    {
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the code contains ‘AT’ keyword.</summary>
    /// <returns>true if the code contains ‘AT’ keyword; otherwise, false.</returns>
    /// <param name="keyword">The keyword.</param>
    protected internal bool At(CSharpKeyword keyword)
    {
      if (this.At(CSharpSymbolType.Keyword))
      {
        CSharpKeyword? keyword1 = this.CurrentSymbol.Keyword;
        if (keyword1.HasValue)
        {
          keyword1 = this.CurrentSymbol.Keyword;
          return keyword1.Value == keyword;
        }
      }
      return false;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parser accepts the ‘IF’ keyword.</summary>
    /// <returns>true if the parser accepts the ‘IF’ keyword; otherwise, false.</returns>
    /// <param name="keyword">The keyword to accept.</param>
    protected internal bool AcceptIf(CSharpKeyword keyword)
    {
      if (!this.At(keyword))
        return false;
      this.AcceptAndMoveNext();
      return true;
    }

    /// <summary>Indicates whether the lines and comments is spacing token.</summary>
    /// <returns>The function that indicates the spacing token.</returns>
    /// <param name="includeNewLines">true to include new lines; otherwise, false.</param>
    /// <param name="includeComments">true to include comments; otherwise, false.</param>
    protected static Func<CSharpSymbol, bool> IsSpacingToken(
      bool includeNewLines,
      bool includeComments)
    {
      return (Func<CSharpSymbol, bool>) (sym =>
      {
        if (sym.Type == CSharpSymbolType.WhiteSpace || includeNewLines && sym.Type == CSharpSymbolType.NewLine)
          return true;
        return includeComments && sym.Type == CSharpSymbolType.Comment;
      });
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Blocks the parsing.</summary>
    public override void ParseBlock()
    {
      using (this.PushSpanConfig(new Action<SpanBuilder>(this.DefaultSpanConfig)))
      {
        if (this.Context == null)
          throw new InvalidOperationException(RazorResources.Parser_Context_Not_Set);
        using (this.Context.StartBlock(BlockType.Statement))
        {
          this.NextToken();
          this.AcceptWhile(CSharpCodeParser.IsSpacingToken(true, true));
          CSharpSymbol currentSymbol = this.CurrentSymbol;
          if (this.At(CSharpSymbolType.StringLiteral) && this.CurrentSymbol.Content.Length > 0 && (int) this.CurrentSymbol.Content[0] == (int) SyntaxConstants.TransitionCharacter)
          {
            Tuple<CSharpSymbol, CSharpSymbol> tuple = this.Language.SplitSymbol(this.CurrentSymbol, 1, CSharpSymbolType.Transition);
            currentSymbol = tuple.Item1;
            this.Context.Source.Position = tuple.Item2.Start.AbsoluteIndex;
            this.NextToken();
          }
          else if (this.At(CSharpSymbolType.Transition))
            this.NextToken();
          if (currentSymbol.Type == CSharpSymbolType.Transition)
          {
            if (this.Span.Symbols.Count > 0)
              this.Output(SpanKind.Code);
            this.AtTransition(currentSymbol);
          }
          else
            this.AfterTransition();
          this.Output(SpanKind.Code);
        }
      }
    }

    private void DefaultSpanConfig(SpanBuilder span)
    {
      span.EditHandler = SpanEditHandler.CreateDefault(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString));
      span.CodeGenerator = (ISpanCodeGenerator) new StatementCodeGenerator();
    }

    private void AtTransition(CSharpSymbol current)
    {
      this.Accept(current);
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Span.CodeGenerator = SpanCodeGenerator.Null;
      this.Output(SpanKind.Transition);
      this.AfterTransition();
    }

    private void AfterTransition()
    {
      using (this.PushSpanConfig(new Action<SpanBuilder>(this.DefaultSpanConfig)))
      {
        this.EnsureCurrent();
        try
        {
          if (!this.EndOfFile)
          {
            if (this.CurrentSymbol.Type == CSharpSymbolType.LeftParenthesis)
            {
              this.Context.CurrentBlock.Type = new BlockType?(BlockType.Expression);
              this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new ExpressionCodeGenerator();
              this.ExplicitExpression();
              return;
            }
            if (this.CurrentSymbol.Type == CSharpSymbolType.Identifier)
            {
              Action handler;
              if (this.TryGetDirectiveHandler(this.CurrentSymbol.Content, out handler))
              {
                this.Span.CodeGenerator = SpanCodeGenerator.Null;
                handler();
                return;
              }
              this.Context.CurrentBlock.Type = new BlockType?(BlockType.Expression);
              this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new ExpressionCodeGenerator();
              this.ImplicitExpression();
              return;
            }
            if (this.CurrentSymbol.Type == CSharpSymbolType.Keyword)
            {
              this.KeywordBlock(true);
              return;
            }
            if (this.CurrentSymbol.Type == CSharpSymbolType.LeftBrace)
            {
              this.VerbatimBlock();
              return;
            }
          }
          this.Context.CurrentBlock.Type = new BlockType?(BlockType.Expression);
          this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new ExpressionCodeGenerator();
          this.AddMarkerSymbolIfNecessary();
          this.Span.CodeGenerator = (ISpanCodeGenerator) new ExpressionCodeGenerator();
          SpanBuilder span = this.Span;
          ImplicitExpressionEditHandler expressionEditHandler = new ImplicitExpressionEditHandler(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString), CSharpCodeParser.DefaultKeywords, this.IsNested);
          expressionEditHandler.AcceptedCharacters = AcceptedCharacters.NonWhiteSpace;
          span.EditHandler = (SpanEditHandler) expressionEditHandler;
          if (this.At(CSharpSymbolType.WhiteSpace) || this.At(CSharpSymbolType.NewLine))
            this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS);
          else if (this.EndOfFile)
            this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock);
          else
            this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS, (object) this.CurrentSymbol.Content);
        }
        finally
        {
          this.PutCurrentBack();
        }
      }
    }

    private void VerbatimBlock()
    {
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(RazorResources.BlockName_Code, this.CurrentLocation);
      this.AcceptAndMoveNext();
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Span.CodeGenerator = SpanCodeGenerator.Null;
      this.Output(SpanKind.MetaCode);
      AutoCompleteEditHandler completeEditHandler = new AutoCompleteEditHandler(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString));
      this.Span.EditHandler = (SpanEditHandler) completeEditHandler;
      this.CodeBlock(false, block);
      this.Span.CodeGenerator = (ISpanCodeGenerator) new StatementCodeGenerator();
      this.AddMarkerSymbolIfNecessary();
      if (!this.At(CSharpSymbolType.RightBrace))
        completeEditHandler.AutoCompleteString = "}";
      this.Output(SpanKind.Code);
      if (this.Optional(CSharpSymbolType.RightBrace))
      {
        this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
        this.Span.CodeGenerator = SpanCodeGenerator.Null;
      }
      if (!this.At(CSharpSymbolType.WhiteSpace) && !this.At(CSharpSymbolType.NewLine))
        this.PutCurrentBack();
      this.CompleteBlock(false);
      this.Output(SpanKind.MetaCode);
    }

    private void ImplicitExpression()
    {
      this.Context.CurrentBlock.Type = new BlockType?(BlockType.Expression);
      this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new ExpressionCodeGenerator();
      using (this.PushSpanConfig((Action<SpanBuilder>) (span =>
      {
        span.EditHandler = (SpanEditHandler) new ImplicitExpressionEditHandler(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString), this.Keywords, this.IsNested);
        span.EditHandler.AcceptedCharacters = AcceptedCharacters.NonWhiteSpace;
        span.CodeGenerator = (ISpanCodeGenerator) new ExpressionCodeGenerator();
      })))
      {
        do
        {
          if (this.AtIdentifier(true))
            this.AcceptAndMoveNext();
        }
        while (this.MethodCallOrArrayIndex());
        this.PutCurrentBack();
        this.Output(SpanKind.Code);
      }
    }

    private bool MethodCallOrArrayIndex()
    {
      if (!this.EndOfFile)
      {
        if (this.CurrentSymbol.Type == CSharpSymbolType.LeftParenthesis || this.CurrentSymbol.Type == CSharpSymbolType.LeftBracket)
        {
          this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
          CSharpSymbolType type;
          bool flag;
          using (this.PushSpanConfig((Action<SpanBuilder, Action<SpanBuilder>>) ((span, prev) =>
          {
            prev(span);
            span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
          })))
          {
            type = this.Language.FlipBracket(this.CurrentSymbol.Type);
            flag = this.Balance(BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates);
          }
          if (!flag)
            this.AcceptUntil(CSharpSymbolType.LessThan);
          if (this.At(type))
          {
            this.AcceptAndMoveNext();
            this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.NonWhiteSpace;
          }
          return this.MethodCallOrArrayIndex();
        }
        if (this.CurrentSymbol.Type == CSharpSymbolType.Dot)
        {
          CSharpSymbol currentSymbol = this.CurrentSymbol;
          if (this.NextToken())
          {
            if (this.At(CSharpSymbolType.Identifier) || this.At(CSharpSymbolType.Keyword))
            {
              this.Accept(currentSymbol);
              return true;
            }
            this.PutCurrentBack();
          }
          if (!this.IsNested)
            this.PutBack(currentSymbol);
          else
            this.Accept(currentSymbol);
        }
        else if (!this.At(CSharpSymbolType.WhiteSpace) && !this.At(CSharpSymbolType.NewLine))
          this.PutCurrentBack();
      }
      return false;
    }

    private void CompleteBlock() => this.CompleteBlock(true);

    private void CompleteBlock(bool insertMarkerIfNecessary) => this.CompleteBlock(insertMarkerIfNecessary, insertMarkerIfNecessary);

    private void CompleteBlock(bool insertMarkerIfNecessary, bool captureWhitespaceToEndOfLine)
    {
      if (insertMarkerIfNecessary && this.Context.LastAcceptedCharacters != AcceptedCharacters.Any)
        this.AddMarkerSymbolIfNecessary();
      this.EnsureCurrent();
      int num1;
      if (!this.Context.WhiteSpaceIsSignificantToAncestorBlock)
      {
        BlockType? type = this.Context.CurrentBlock.Type;
        BlockType blockType = BlockType.Expression;
        num1 = !(type.GetValueOrDefault() == blockType & type.HasValue) ? 1 : 0;
      }
      else
        num1 = 0;
      int num2 = captureWhitespaceToEndOfLine ? 1 : 0;
      if ((num1 & num2) != 0 && !this.Context.DesignTimeMode && !this.IsNested)
        this.CaptureWhitespaceAtEndOfCodeOnlyLine();
      else
        this.PutCurrentBack();
    }

    private void CaptureWhitespaceAtEndOfCodeOnlyLine()
    {
      IEnumerable<CSharpSymbol> symbols = this.ReadWhile((Func<CSharpSymbol, bool>) (sym => sym.Type == CSharpSymbolType.WhiteSpace));
      if (this.At(CSharpSymbolType.NewLine))
      {
        this.Accept(symbols);
        this.AcceptAndMoveNext();
        this.PutCurrentBack();
      }
      else
      {
        this.PutCurrentBack();
        this.PutBack(symbols);
      }
    }

    private void ConfigureExplicitExpressionSpan(SpanBuilder sb)
    {
      sb.EditHandler = SpanEditHandler.CreateDefault(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString));
      sb.CodeGenerator = (ISpanCodeGenerator) new ExpressionCodeGenerator();
    }

    private void ExplicitExpression()
    {
      CSharpCodeParser.Block block = new CSharpCodeParser.Block(RazorResources.BlockName_ExplicitExpression, this.CurrentLocation);
      this.AcceptAndMoveNext();
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Span.CodeGenerator = SpanCodeGenerator.Null;
      this.Output(SpanKind.MetaCode);
      using (this.PushSpanConfig(new Action<SpanBuilder>(this.ConfigureExplicitExpressionSpan)))
      {
        if (!this.Balance(BalancingModes.BacktrackOnFailure | BalancingModes.NoErrorOnFailure | BalancingModes.AllowCommentsAndTemplates, CSharpSymbolType.LeftParenthesis, CSharpSymbolType.RightParenthesis, block.Start))
        {
          this.AcceptUntil(CSharpSymbolType.LessThan);
          this.Context.OnError(block.Start, RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, (object) block.Name, (object) ")", (object) "(");
        }
        if (this.Span.Symbols.Count == 0)
          this.Accept(new CSharpSymbol(this.CurrentLocation, string.Empty, CSharpSymbolType.Unknown));
        this.Output(SpanKind.Code);
      }
      this.Optional(CSharpSymbolType.RightParenthesis);
      if (!this.EndOfFile)
        this.PutCurrentBack();
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.Span.CodeGenerator = SpanCodeGenerator.Null;
      this.CompleteBlock(false);
      this.Output(SpanKind.MetaCode);
    }

    private void Template()
    {
      if (this.Context.IsWithin(BlockType.Template))
        this.Context.OnError(this.CurrentLocation, RazorResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested);
      this.Output(SpanKind.Code);
      using (this.Context.StartBlock(BlockType.Template))
      {
        this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new TemplateBlockCodeGenerator();
        this.PutCurrentBack();
        this.OtherParserBlock();
      }
    }

    private void OtherParserBlock() => this.ParseWithOtherParser((Action<ParserBase>) (p => p.ParseBlock()));

    private void SectionBlock(string left, string right, bool caseSensitive) => this.ParseWithOtherParser((Action<ParserBase>) (p => p.ParseSection(Tuple.Create<string, string>(left, right), caseSensitive)));

    private void NestedBlock()
    {
      this.Output(SpanKind.Code);
      bool isNested = this.IsNested;
      this.IsNested = true;
      using (this.PushSpanConfig())
        this.ParseBlock();
      this.Initialize(this.Span);
      this.IsNested = isNested;
      this.NextToken();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the code is at embedded transition.</summary>
    /// <returns>true if the code is at embedded transition; otherwise, false.</returns>
    /// <param name="allowTemplatesAndComments">true to allow templates and comments; otherwise, false.</param>
    /// <param name="allowTransitions">true to allow transitions; otherwise, false.</param>
    protected override bool IsAtEmbeddedTransition(
      bool allowTemplatesAndComments,
      bool allowTransitions)
    {
      if (!allowTemplatesAndComments)
        return false;
      if (this.Language.IsTransition(this.CurrentSymbol))
      {
        if (this.NextIs(CSharpSymbolType.LessThan, CSharpSymbolType.Colon))
          return true;
      }
      return this.Language.IsCommentStart(this.CurrentSymbol);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the code that handles embedded transition.</summary>
    protected override void HandleEmbeddedTransition()
    {
      if (this.Language.IsTransition(this.CurrentSymbol))
      {
        this.PutCurrentBack();
        this.Template();
      }
      else
      {
        if (!this.Language.IsCommentStart(this.CurrentSymbol))
          return;
        this.RazorComment();
      }
    }

    private void ParseWithOtherParser(Action<ParserBase> parseAction)
    {
      using (this.PushSpanConfig())
      {
        this.Context.SwitchActiveParser();
        parseAction(this.Context.MarkupParser);
        this.Context.SwitchActiveParser();
      }
      this.Initialize(this.Span);
      this.NextToken();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Represents the block for this CSharpCode parser.</summary>
    protected class Block
    {
      /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Parser.CSharpCodeParser.Block" /> class.</summary>
      /// <param name="name">The string name.</param>
      /// <param name="start">The start of the source location.</param>
      public Block(string name, SourceLocation start)
      {
        this.Name = name;
        this.Start = start;
      }

      /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Parser.CSharpCodeParser.Block" /> class.</summary>
      /// <param name="symbol">The CSharp symbol.</param>
      public Block(CSharpSymbol symbol)
        : this(CSharpCodeParser.Block.GetName(symbol), symbol.Start)
      {
      }

      /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the string name for the block.</summary>
      /// <returns>The string name for the block.</returns>
      public string Name { get; set; }

      /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the source location to start the block.</summary>
      /// <returns>The source location to start the block.</returns>
      public SourceLocation Start { get; set; }

      private static string GetName(CSharpSymbol sym) => sym.Type == CSharpSymbolType.Keyword ? CSharpLanguageCharacteristics.GetKeyword(sym.Keyword.Value) : sym.Content;
    }
  }
}
